package gui.panel_new.evaluation.professor;

import enums.ExportOptionsEnum;
import enums.TextBundleEnum;
import enums.URLEnum;
import gui.other.JComponentCellRenderer;
import gui.other.JComponentCellRendererStringContext;
import gui.panel_new.OpenSavePanel;
import j_util.Utiles;
import j_util.comparators.ComparableObjectsComparator;
import j_util.sorters.BubbleSort;
import misc.BundlesProvider;
import misc.ExportDataPreferences;
import misc.StudentSortingData;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.*;
import java.util.List;
/*

    This file is part of Logica-Logike.

    Logica-Logike is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation version 3 of the License.

    Logica-Logike is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with Logica-Logike.  If not, see <http://www.gnu.org/licenses/>.

 */
/**
 * Extiende de JPanel, destinado a mostrar los resultados de la evaluacion en curso en forma de tabla.
 * Usada para la parte servidor, brindando datos al profesor;
 *
 * @author Jose Martin Rozanec;
 */
public class StudentMarksPanel extends OpenSavePanel {
    private ResourceBundle textBundle = BundlesProvider.getBundle(URLEnum.TEXT_BUNDLE);
    private JTable table;
    private String[] titles;
    private JLabel[][] content;
    private Map<String, Integer> studentsMap;
    private int nextStudent = 0;

    private ExportDataPreferences exportDataPreferences;

    /**
     * Constructor;
     *
     * @param students - cantidad de educandos;
     */
    public StudentMarksPanel(int students,ExportDataPreferences exportPreferences,
                             JButton saveButton, JButton openButton, JFileChooser fileChooser) {
        this.saveButton = saveButton;
        this.openButton = openButton;
        this.fileChooser = fileChooser;
        initLabelsMatrix(students);
        this.exportDataPreferences=exportPreferences;
        fileFilter = exportPreferences.getExportAs();
        initTable();
        studentsMap = new HashMap<String, Integer>();
    }

    /**
     * Agrega los datos referidos a un estudiante;
     *
     * @param surname;
     * @param name;
     * @param studentNumber;
     * @param mark;
     */
    public void addStudentMark(String surname, String name, String studentNumber, String mark) {
        if (studentsMap.get(surname + name + studentNumber) == null) {
            content[nextStudent][0].setText(surname);
            content[nextStudent][1].setText(name);
            content[nextStudent][2].setText(studentNumber);
            content[nextStudent][3].setText(mark);
            content[nextStudent][4].setText(textBundle.getString(TextBundleEnum.NO.toString()));
            studentsMap.put(surname + name + studentNumber, nextStudent);
            nextStudent++;
        } else {
            content[studentsMap.get(surname + name + studentNumber)][4].setText(
                    textBundle.getString(TextBundleEnum.YES.toString()));
        }

        table.setModel(new javax.swing.table.DefaultTableModel(
                content, titles
        ) {//this prevents the table being editable!

            public boolean isCellEditable(int row, int column) {
                return false;
            }
        });
        JLabel label;
        for (int j = 0; j < 4; j++) {
            table.getColumnModel().getColumn(j).setCellRenderer(new JComponentCellRenderer());
            for (int i = 0; i < table.getRowCount(); i++) {
                label = ((JLabel) table.getModel().getValueAt(i, j));
                if (content[i][4].getText().equals(textBundle.getString(TextBundleEnum.YES.toString()))) {
                    label.setBackground(new Color(255, 100, 100));
                } else {
                    label.setBackground(Color.WHITE);
                }
            }
        }
        table.getColumnModel().getColumn(4).setCellRenderer(new JComponentCellRendererStringContext(
                textBundle.getString(TextBundleEnum.YES.toString()), new Color(255, 100, 100), Color.WHITE));
    }

    /**
     * Inicializa la tabla;
     */
    private void initTable() {
        JScrollPane scrollPane = new JScrollPane();
        add(scrollPane);
        titles = new String[]{
                textBundle.getString(TextBundleEnum.SURNAMES.toString()),
                textBundle.getString(TextBundleEnum.NAMES.toString()),
                textBundle.getString(TextBundleEnum.STUDENT_NUMBER.toString()),
                textBundle.getString(TextBundleEnum.CALIFICACION.toString())+" (%)",
                textBundle.getString(TextBundleEnum.CHEAT_TRY.toString())
        };
        table = new JTable(content, titles);
        scrollPane.setViewportView(table);
        scrollPane.setBackground(new java.awt.Color(255, 255, 255));
        scrollPane.setBorder(null);
        scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
        scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        scrollPane.setViewportView(table);
        scrollPane.setPreferredSize(new Dimension(680, 660));

        table.setModel(new javax.swing.table.DefaultTableModel(
                content, titles
        ) {//this prevents the table being editable!

            public boolean isCellEditable(int row, int column) {
                return false;
            }
        });
        table.getTableHeader().setReorderingAllowed(false);
        JLabel label;
        for (int j = 0; j < 5; j++) {
            label = new JLabel(titles[j]);
            label.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
            label.setFont(new Font("Tahoma", 1, 12));
            table.getColumnModel().getColumn(j).setHeaderRenderer(new JComponentCellRenderer());
            table.getColumnModel().getColumn(j).setHeaderValue(label);
        }
        for (int j = 0; j < 5; j++) {
            table.getColumnModel().getColumn(j).setHeaderRenderer(new JComponentCellRenderer());
            table.getColumnModel().getColumn(j).setCellRenderer(new JComponentCellRenderer());
        }
        table.getTableHeader().revalidate();

//        table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
//        scrollPane.setViewportView(table);
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        StudentMarksPanel studentMarksPanel = new StudentMarksPanel(15,
                new ExportDataPreferences(), new JButton(),new JButton(),new JFileChooser());
        frame.setContentPane(studentMarksPanel);
        frame.pack();
        frame.setPreferredSize(new Dimension(500, 500));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        for (int j = 0; j < 12; j++) {
            studentMarksPanel.addStudentMark("A" + j, "B", "C", "10");
            frame.validate();
        }
        studentMarksPanel.addStudentMark("A" + 7, "B", "C", "10");
        studentMarksPanel.addStudentMark("A" + 10, "B", "C", "10");
    }

    private void initLabelsMatrix(int students) {
        content = new JLabel[students][5];
        for (int j = 0; j < students; j++) {
            for (int s = 0; s < 5; s++) {
                content[j][s] = new JLabel(" ");
                content[j][s].setOpaque(true);
            }
        }
    }

    protected void setSaveActionListener() {
        class SaveTestAction extends AbstractAction {
            public SaveTestAction() {
                super("", Utiles.createImageIcon(URLEnum.getReference(URLEnum.SAVE_AS)));
            }

            public void actionPerformed(ActionEvent e) {
                exportData();
                JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
                        textBundle.getString(TextBundleEnum.WARNING_SUCCESFULLY_EXPORTED_DATA.toString()));
            }
        }
        saveButton.setAction(new SaveTestAction());
    }

    protected void setSaveButtonEnabled() {
        saveButton.setEnabled(true);
    }

    protected void setOpenActionListener() {
        class OpenTestAction extends AbstractAction {
            public OpenTestAction() {
                super("", Utiles.createImageIcon(URLEnum.getReference(URLEnum.OPEN)));
            }

            public void actionPerformed(ActionEvent e) {
                //remains unimplemented
            }
        }
        openButton.setAction(new OpenTestAction());
    }

    protected void setOpenButtonEnabled() {
        openButton.setEnabled(false);
    }

    protected void setFocusOnComponent() {
        //remains unimplemented
    }

    private void exportData() {
        StringBuffer txtString = new StringBuffer();
        txtString.append(textBundle.getString(TextBundleEnum.SURNAMES.toString()) + "," +
                textBundle.getString(TextBundleEnum.NAMES.toString()) + "," +
                textBundle.getString(TextBundleEnum.STUDENT_NUMBER.toString()) + "," +
                textBundle.getString(TextBundleEnum.CALIFICACION.toString()) + "," +
                textBundle.getString(TextBundleEnum.CHEAT_TRY.toString()));
        txtString.append(getSortedData());

        String filePath = exportDataPreferences.getPath() + exportDataPreferences.getTestName();

        switch (exportDataPreferences.getExportAs()) {
            case TXT:
                RandomAccessFile raf = null;
                try {
                    raf = new RandomAccessFile(filePath + ".txt", "rw");
                    raf.writeUTF(txtString.toString());
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                break;
            case XLS:
                Utiles.exportToXLS(filePath,txtString.toString(),
                        textBundle.getString(TextBundleEnum.NOTAS_ALUMNOS.toString()));
                break;
            case XLSX:
                Utiles.exportToXLSX(filePath,txtString.toString(),
                        textBundle.getString(TextBundleEnum.NOTAS_ALUMNOS.toString()));
                break;
        }
    }

    private String getSortedData() {
        StringBuffer txtString = new StringBuffer();
        BubbleSort sorter = new BubbleSort();
        List<StudentSortingData> list = buildSortingList(exportDataPreferences.getSortBy());
        sorter.sort(list, new ComparableObjectsComparator());
        if (exportDataPreferences.getSortAscendingDescending().equals(ExportOptionsEnum.ASCENDING)) {
            for (int j = 0; j < nextStudent; j++) {
                txtString.append(list.get(j).toString());
            }
        } else {
            for (int j = nextStudent; j > -1; j--) {
                txtString.append(list.get(j).toString());
            }
        }
        return txtString.toString();
    }

    private List<StudentSortingData> buildSortingList(ExportOptionsEnum sortBy) {
        StudentSortingData sortingData;
        List<StudentSortingData> sortingDataList = new ArrayList<StudentSortingData>();
        for (int j = 0; j < nextStudent; j++) {
            sortingData = new StudentSortingData(content[j][0].getText() + "," + content[j][1].getText(),
                    Double.parseDouble(content[j][3].getText()), "\n" + content[j][0].getText() + "," +
                    content[j][1].getText() + "," + content[j][2].getText() + "," +
                    content[j][3].getText() + "," + content[j][4].getText());
            sortingData.setCompareBy(sortBy);
            sortingDataList.add(sortingData);
        }
        return sortingDataList;
    }
}
